﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
namespace DisplayBoardInfoClient
{
    /// <summary>
    /// Okno pozwalające użytkownikowi na zalogowanie się do danego typu aplikacji.
    /// </summary>
    public partial class LoggingWindow : Window
    {
        /// <summary>
        /// Zmienna przechowująca informację czy po utworzeniu okna należy je zamknąć.
        /// </summary>
        private bool close = false;
        /// <summary>
        /// Konstruktor tworzący okno i odczytujący plik konfiguracyjny.
        /// </summary>
        public LoggingWindow()
        {
            InitializeComponent();
            try
            {
                XMLConfiguration.init(Constants.CONF_FILE_PATH);
            }
            catch (Exception e)
            {
                MessageBox.Show("Nie udało się zainicjować pliku konfiguracyjnego. Sprawdzć poprawności i obecność pliku.");
                close = true;
            }
        }
        /// <summary>
        /// Obsługa przycisku anuluj. Powoduje zamknięcei okna.
        /// </summary>
        /// <param name="sender">obiekt wysyłający zdarzenie</param>
        /// <param name="e">dodatkowe argumenty zdarzenia</param>
        private void buttonAnuluj_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
        /// <summary>
        /// Obsługa kliknięcia przycisku zaloguj. Weryfikuje wprowadzone dane i wysyła je do serwera w celu uwierzytelnienia. Autoryzuje dostęp i tworzy odpowiednie okno.
        /// </summary>
        /// <param name="sender">obiekt wysyłający zdarzenie</param>
        /// <param name="e">dodatkowe parametry zdarzenia</param>
        private void buttonLoguj_Click(object sender, RoutedEventArgs e)
        {
            if (passwordBox.Password.Equals("") || loginBox.Text.Equals(""))
            {
                MessageBox.Show("Należy wprowadzić login oraz hasło.");
                return;
            }
            SHA1 crypt = SHA1.Create();
            System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();
            byte[] combined = encoder.GetBytes(passwordBox.Password.ToCharArray());
            byte[] resofHash = crypt.ComputeHash(combined);
            string hashPass = Convert.ToBase64String(crypt.Hash);
            String login = loginBox.Text;
            String permission = "";
            switch (typeBox.SelectedIndex)
            {
                case 0: permission = "d"; break;
                case 2: permission = "s"; break;
                case 1: permission = "r"; break;
            }
            if (permission.Equals(""))
            {
                MessageBox.Show("Wybrano niepoprawny typ aplikacji!");
                return;
            }
            //string lista = ServerClient.sendRequestGET(XMLConfiguration.get(Constants.SERVER_ADDR) + "patients/list");
            // MessageBox.Show("Dostałem:" + lista);

            if (!ServerClient.authorize(login, hashPass))
            {
                MessageBox.Show("Brak takiego konta w systemie.");
                return;
            }
            if (permission != LoggedAs.Type)
            {
                MessageBox.Show("Brak uprawnień do tego typu aplikacji.");
                return;
            }
            if (!permission.Equals("r"))
            {
                try
                {
                    WebServiceHost service = new WebServiceHost(typeof(ListenForUpdateService),
                        new Uri("http://" + XMLConfiguration.get(Constants.LISTENING_SERVICE_IP) + ":" + XMLConfiguration.get(Constants.LISTENING_SERVICE_PORT) + ""));
                   
                    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                    smb.HttpGetEnabled = true;
                   // smb.HttpGetBinding = new System.ServiceModel.BasicHttpBinding();
                    service.Description.Behaviors.Add(smb);
                    
                    // Open the ServiceHost to start listening for messages. Since
                    // no endpoints are explicitly configured, the runtime will create
                    // one endpoint per base address for each service contract implemented
                    // by the service.
                    service.Open();
                    MessageBox.Show("The service is ready at " + "http://" + XMLConfiguration.get(Constants.LISTENING_SERVICE_IP) + ":" + XMLConfiguration.get(Constants.LISTENING_SERVICE_PORT) + "/update");
                }
                catch (Exception)
                {
                    MessageBox.Show("Nie udało się zainicjować usługi. Szprawdź czy aplikacja jest uruchomiona z uprawnieniami administratora i czy adres usługi jest poprawny.");
                    this.Close();
                }

            }
            switch (typeBox.SelectedIndex)
            {
                case 0: DoctorWindow newWind = new DoctorWindow(); Constants.windowdoc = newWind; newWind.Show(); break;
                case 2: DisplayWindow newWind2 = new DisplayWindow(); Constants.windowdis = newWind2; newWind2.Show(); break;
                case 1: ReceptionWindow newWind3 = new ReceptionWindow(); newWind3.Show(); break;
            }
            this.Close();


        }
        /// <summary>
        /// Metoda zamyka okno jeżeli nie udało się wczytać konfiguracji z pliku.
        /// </summary>
        /// <param name="sender">obiekt wysyłający zdarzenie</param>
        /// <param name="e">dodatkowe parametry zdarzenia</param>
        private void Oknoglowne_Loaded(object sender, RoutedEventArgs e)
        {
            if (close)
            {
                this.Close();
                return;
            }
        }
    }
}
